package com.zyg.cod.util;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * map转xml 工具类
 * @author allen-zyg
 * @date 2021/1/26
 */
public class Map2XmlUtil {
    /**
     * map转xml map中没有根节点的键
     */
    public static String map2Xml(Map<String, Object> map, String rootName) throws Exception  {
        try{
            Document doc = DocumentHelper.createDocument();
            Element root = DocumentHelper.createElement(rootName);
            doc.add(root);
            map2Xml(map, root);
            return formatXml(doc);
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }

    /**
     * map转xml map中含有根节点的键
     */
    public static Document map2Xml(Map<String, Object> map) throws Exception  {
        try{
            Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
            if(entries.hasNext()){ //获取第一个键创建根节点
                Map.Entry<String, Object> entry = entries.next();
                Document doc = DocumentHelper.createDocument();
                Element root = DocumentHelper.createElement(entry.getKey());
                doc.add(root);
                map2Xml((Map)entry.getValue(), root);
                return doc;
            }
            return null;
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }

    /**
     * map转xml  组装Element
     */
    private static Element map2Xml(Map<String, Object> map, Element body) throws Exception {
        try{
            Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry<String, Object> entry = entries.next();
                String key = entry.getKey();
                Object value = entry.getValue();
                if(key.startsWith("@")){	//属性
                    body.addAttribute(key.substring(1, key.length()), value.toString());
                } else if(key.equals("#text")){	//有属性时的文本
                    body.setText(value.toString());
                } else {
                    if(value instanceof List ){
                        List list = (List)value;
                        Object obj;
                        for(int i=0; i<list.size(); i++){
                            obj = list.get(i);
                            //list里是map或String，不会存在list里直接是list的，
                            if(obj instanceof Map){
                                Element subElement = body.addElement(key);
                                map2Xml((Map)list.get(i), subElement);
                            } else {
                                body.addElement(key).setText((String)list.get(i));
                            }
                        }
                    } else if(value instanceof Map ){
                        Element subElement = body.addElement(key);
                        map2Xml((Map)value, subElement);
                    } else {
                        body.addElement(key).setText(value.toString());
                    }
                }
            }
            return body;
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }

    /**
     * String格式化输出xml
     */
    public static String formatXml(String xmlStr) throws Exception  {
        Document document = DocumentHelper.parseText(xmlStr);
        return formatXml(document);
    }

    /**
     * Document格式化输出xml
     */
    public static String formatXml(Document document) throws Exception  {
        try{
            // 格式化输出格式
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("utf-8");
            StringWriter writer = new StringWriter();
            // 格式化输出流
            XMLWriter xmlWriter = new XMLWriter(writer, format);
            document.getRootElement().asXML();
            // 将document写入到输出流
            xmlWriter.write(document);
            xmlWriter.close();
            return writer.toString();
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }
    }

}
